home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / scan-decls.c < prev    next >
C/C++ Source or Header  |  1993-11-07  |  5KB  |  203 lines

  1. /* scan-decls.c - Extracts declarations from cpp output.
  2.    Copyright (C) 1993 Free Software Foundation, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the
  6. Free Software Foundation; either version 2, or (at your option) any
  7. later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.    Written by Per Bothner <bothner@cygnus.com>, July 1993.  */
  19.  
  20. #include <stdio.h>
  21. #include <ctype.h>
  22. #include "hconfig.h"
  23. #include "scan.h"
  24.  
  25. sstring buf;
  26. sstring rtype;
  27. sstring arg_list;
  28.  
  29. int brace_nesting = 0;
  30.  
  31. /* The first extern_C_braces_length elements of extern_C_braces
  32.    indicate the (brace nesting levels of) left braces that were
  33.    prefixed by extern "C".  */
  34. int extern_C_braces_length = 0;
  35. char extern_C_braces[20];
  36. #define in_extern_C_brace (extern_C_braces_length>0)
  37.  
  38. /* True if the function declaration currently being scanned is
  39.    prefixed by extern "C".  */
  40. int current_extern_C = 0;
  41.  
  42. static void
  43. skip_to_closing_brace (fp)
  44.      FILE *fp;
  45. {
  46.   int nesting = 1;
  47.   for (;;)
  48.     {
  49.       int c = get_token (fp, &buf);
  50.       if (c == EOF)
  51.     break;
  52.       if (c == '{')
  53.     nesting++;
  54.       if (c == '}' && --nesting == 0)
  55.     break;
  56.     }
  57. }
  58.  
  59. /* This function scans a C source file (actually, the output of cpp),
  60.    reading from FP.  It looks for function declarations, and certain
  61.    other interesting sequences (external variables and macros).  */
  62.  
  63. int
  64. scan_decls (fp)
  65.      FILE *fp;
  66. {
  67.   int c;
  68.   int saw_extern, saw_inline;
  69.  
  70.  new_statement:
  71.   c = get_token (fp, &buf);
  72.  handle_statement:
  73.   current_extern_C = 0;
  74.   saw_extern = 0;
  75.   saw_inline = 0;
  76.   if (c == '}')
  77.     {
  78.       /* Pop an 'extern "C"' nesting level, if appropriate.  */
  79.       if (extern_C_braces_length
  80.       && extern_C_braces[extern_C_braces_length - 1] == brace_nesting)
  81.     extern_C_braces_length--;
  82.       brace_nesting--;
  83.       goto new_statement;
  84.     }
  85.   if (c == '{')
  86.     {
  87.       brace_nesting++;
  88.       goto new_statement;
  89.     }
  90.   if (c == EOF)
  91.     return 0;
  92.   if (c == ';')
  93.     goto new_statement;
  94.   if (c != IDENTIFIER_TOKEN)
  95.     goto new_statement;
  96.   rtype.ptr = rtype.base;
  97.   if (SSTRING_LENGTH (&buf) > 16
  98.       && strncmp (buf.base, "__DEFINED_MACRO_", 16) == 0)
  99.     {
  100.       /* For certain interesting macro names, fixproto puts
  101.      #ifdef FOO
  102.      __DEFINED_MACRO_FOO
  103.      #endif
  104.      into the file to be pre-processed.  So if we see __DEFINED_MACRO_FOO,
  105.      it means FOO was defined, which we may want to make a note of.  */
  106.       recognized_macro (buf.base+16);
  107.       goto new_statement;
  108.     }
  109.   if (strcmp (buf.base, "inline") == 0)
  110.     {
  111.       saw_inline = 1;
  112.       c = get_token (fp, &buf);
  113.     }
  114.   if (strcmp (buf.base, "extern") == 0)
  115.     {
  116.       saw_extern = 1;
  117.       c = get_token (fp, &buf);
  118.       if (c == STRING_TOKEN && strcmp (buf.base, "C") == 0)
  119.     {
  120.       current_extern_C = 1;
  121.       c = get_token (fp, &buf);
  122.       if (c == '{')
  123.         {
  124.           brace_nesting++;
  125.           extern_C_braces[extern_C_braces_length++] = brace_nesting;
  126.           goto new_statement;
  127.         }
  128.       c = get_token (fp, &buf);
  129.     }
  130.     }
  131.   for (;;)
  132.     {
  133.       int followingc = getc (fp); /* char following token in buf */
  134.  
  135.       MAKE_SSTRING_SPACE (&rtype, 1);
  136.       *rtype.ptr = 0;
  137.  
  138.       if (c == IDENTIFIER_TOKEN)
  139.     {
  140.       int nextc = skip_spaces (fp, followingc);
  141.       if (nextc == '(')
  142.         {
  143.           int nesting = 1;
  144.           int func_lineno = source_lineno;
  145.           char *args;
  146.  
  147.           arg_list.ptr = arg_list.base;
  148.           for (;;)
  149.         {
  150.           c = getc (fp);
  151.           if (c == '(')
  152.             nesting++;
  153.           else if (c == ')')
  154.             if (--nesting == 0)
  155.               break;
  156.           if (c == EOF)
  157.             break;
  158.           if (c == '\n')
  159.             {
  160.               c = ' ';
  161.               source_lineno++;
  162.               lineno++;
  163.             }
  164.           SSTRING_PUT (&arg_list, c);
  165.         }
  166.           SSTRING_PUT (&arg_list, '\0');
  167.           args = arg_list.base;
  168.           while (*args == ' ')
  169.         args++;
  170.           recognized_function (buf.base,
  171.                    (saw_inline ? 'I'
  172.                     : in_extern_C_brace || current_extern_C
  173.                     ? 'F' : 'f'),
  174.                    rtype.base, args,
  175.                    source_filename.base, func_lineno);
  176.           c = get_token (fp, &buf);
  177.           if (c == '{')
  178.         {
  179.           /* skip body of (normally) inline function */
  180.           skip_to_closing_brace (fp);
  181.           goto new_statement;
  182.         }
  183.           goto handle_statement;
  184.         }
  185.       else if (nextc == ';' && saw_extern)
  186.         {
  187.           recognized_extern (buf.base, rtype.base);
  188.           goto new_statement;
  189.         }
  190.       else
  191.         ungetc (nextc, fp);
  192.     }
  193.       else if (followingc != EOF)
  194.     ungetc (followingc, fp);
  195.       if (c == ';' || c == '{' || c == '}' || c == EOF)
  196.     goto handle_statement;
  197.       sstring_append (&rtype, &buf);
  198.       if (followingc == ' ' || followingc == '\t' || followingc == '\n')
  199.     SSTRING_PUT (&rtype, ' ');
  200.       c = get_token (fp, &buf);
  201.     }
  202. }
  203.